﻿using System;
using System.Reflection;
using Budget.Locator.Installers;
using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Castle.Windsor.Installer;
using CommonServiceLocator.WindsorAdapter;
using Microsoft.Practices.ServiceLocation;

namespace Budget.Locator
{
    public static class IoC
    {
        private static IWindsorContainer container;

        static IoC()
        {
            ServiceLocator.SetLocatorProvider(() => null);
        }

        public static IServiceLocator Locator
        {
            get
            {
                if (ServiceLocator.Current == null)
                {
                    Init();
                }

                return ServiceLocator.Current;
            }
        }

        public static void Init()
        {
            try
            {
                container = new WindsorContainer();
                //container.AddFacility<FactorySupportFacility>();
                //container.AddFacility<WcfFacility>();

                container.Install(FromAssembly.InThisApplication());

                ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
            }
            catch (Exception ex)
            {
                throw new ApplicationException("IoC installation exception", ex);
            }
        }

        public static void UnInit()
        {
            if (container != null)
            {
                container.Dispose();
            }
            ServiceLocator.SetLocatorProvider(() => null);
        }

        public static bool HasComponent(Type type)
        {
            return container.Kernel.HasComponent(type);
        }

        public static void RegisterAssembly<T>(Assembly assembly)
        {
            container.Register(Classes.FromAssembly(assembly).BasedOn<T>().LifestyleTransient());
        }

        public static void Release(object instance)
        {
            container.Kernel.ReleaseComponent(instance);
        }
    }
}